import typing

import openstack.config
import openstack.connection
from openstack import proxy
from openstack.cloud._network import NetworkCloudMixin
from openstack.connection import Connection


class _NetworkCloudMixin(NetworkCloudMixin):
    def create_tap_service(self, port_id, name=None):
        tap_service = {"port_id": port_id}
        if name:
            tap_service["name"] = name
        data = proxy._json_response(
            self.network.post("taas/tap_services", json={"tap_service": tap_service})
        )
        return data

    def delete_tap_service(self, tap_service_id):
        self.network.delete(f"taas/tap_services/{tap_service_id}")

    def create_tap_flow(self, port_id, service_id, name=None):
        flow = {
            "source_port": port_id,
            "tap_service_id": service_id,
            "direction": "BOTH",
        }
        if name:
            flow["name"] = name
        data = proxy._json_response(
            self.network.post("taas/tap_flows", json={"tap_flow": flow})
        )
        return data

    def delete_flow(self, flow_id):
        self.network.delete(f"taas/tap_flows/{flow_id}")

    def get_flows(self, filters=None):
        if not filters:
            filters = {}
        date = proxy._json_response(self.network.get("taas/tap_flows", params=filters))
        return date


class _Connection(Connection, _NetworkCloudMixin):
    pass


def connect(
    cloud=None,
    app_name=None,  # type: typing.Optional[str]
    app_version=None,  # type: typing.Optional[str]
    options=None,
    load_yaml_config=True,  # type: bool
    load_envvars=True,  # type: bool
    **kwargs,
):
    # type: (...) -> openstack.connection.Connection
    """Create a :class:`~openstack.connection.Connection`

    :param string cloud:
        The name of the configuration to load from clouds.yaml. Defaults
        to 'envvars' which will load configuration settings from environment
        variables that start with ``OS_``.
    :param argparse.Namespace options:
        An argparse Namespace object. allows direct passing in of
        argparse options to be added to the cloud configs.  Values
        of None and '' will be removed.
    :param bool load_yaml_config:
        Whether or not to load configs settings from clouds.yaml files.
        Defaults to True.
    :param bool load_envvars:
        Whether or not to load configs settings from environment variables.
        Defaults to True.
    :param kwargs:
        Additional configuration options.

    :returns: openstack.connnection.Connection
    :raises: keystoneauth1.exceptions.MissingRequiredOptions
        on missing required libs parameters
    """
    cloud_region = openstack.config.get_cloud_region(
        cloud=cloud,
        app_name=app_name,
        app_version=app_version,
        load_yaml_config=load_yaml_config,
        load_envvars=load_envvars,
        options=options,
        **kwargs,
    )
    return _Connection(config=cloud_region, vendor_hook=kwargs.get("vendor_hook"))
